home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cfengine-1.5.3 / src / parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-08-03  |  30.4 KB  |  1,257 lines

  1. /* cfengine for GNU
  2.  
  3.         Copyright (C) 1995
  4.         Free Software Foundation, Inc.
  5.  
  6.    This file is part of GNU cfengine - written and maintained 
  7.    by Mark Burgess, Dept of Computing and Engineering, Oslo College,
  8.    Dept. of Theoretical physics, University of Oslo
  9.  
  10.    This program is free software; you can redistribute it and/or modify it
  11.    under the terms of the GNU General Public License as published by the
  12.    Free Software Foundation; either version 2, or (at your option) any
  13.    later version.
  14.  
  15.    This program is distributed in the hope that it will be useful,
  16.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.    GNU General Public License for more details.
  19.  
  20.   You should have received a copy of the GNU General Public License
  21.   along with this program; if not, write to the Free Software
  22.   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
  23.  
  24. */
  25.  
  26.  
  27. /*******************************************************************/
  28. /*                                                                 */
  29. /*  Parse Zone for cfengine                                        */
  30. /*                                                                 */
  31. /*  This is wide screen entertainment. Resize                      */
  32. /*  your window before viewing!                                    */
  33. /*                                                                 */
  34. /*  The routines here are called by the lexer and the yacc parser  */
  35. /*                                                                 */
  36. /*******************************************************************/
  37.  
  38.  /*
  39.     The parser uses the classification of strings into id's items
  40.     paths, varpaths etc. Each complete action is gradually assembled
  41.     by setting flags based on what action, class etc is being
  42.     parsed. e.g. HAVEPATH, FROM_LINK etc.. these are typed as
  43.     "flag" in the variables file. When all the necessary critera
  44.     are met, or the beginning of a new definition is found
  45.     the action gets completed and installed in the actions lists.
  46.  
  47.   */
  48.  
  49. #define INET
  50.  
  51. #include <stdio.h>
  52. #include "cf.defs.h"
  53. #include "cf.extern.h"
  54.  
  55. extern FILE *yyin;
  56.  
  57. /*******************************************************************/
  58.  
  59. ParseInputFiles()
  60.  
  61. { struct Item *ptr;
  62.   char filename[bufsize], *sp;
  63.   void TimeOut();
  64.  
  65. if ((strcmp(VINPUTFILE,".") == 0)||(strcmp(VINPUTFILE,"-") == 0)) /* read from standard input */
  66.    {
  67.    yyin = stdin;
  68.  
  69.    if (!feof(yyin))
  70.       {
  71.       yyparse();
  72.       }
  73.  
  74.    InstallPending(ACTION);
  75.    }
  76. else
  77.    {
  78.    filename[0] = '\0';
  79.  
  80.    if ((sp=getenv(CFINPUTSVAR)) != NULL)
  81.       {
  82.       if (! IsAbsoluteFileName(VINPUTFILE))     /* Don't prepend to absolute names */
  83.      { 
  84.      strcpy(filename,sp);
  85.      if (filename[strlen(filename)-1] != '/')
  86.         {
  87.         strcat(filename,"/");
  88.         }
  89.      }
  90.       }
  91.    
  92.    strcat(filename,VINPUTFILE);
  93.  
  94.    signal(SIGALRM,(void *)TimeOut);
  95.    alarm(RPCTIMEOUT);
  96.  
  97.    if (!FileSecure(filename))
  98.       {
  99.       FatalError("Security exception");
  100.       }
  101.    
  102.    if ((yyin = fopen(filename,"r")) == NULL)      /* Open root file */
  103.       {
  104.       if (sp == NULL)
  105.      {
  106.      printf("%s: (%s is set to <nothing>)\n",VPREFIX,CFINPUTSVAR);
  107.      }
  108.       else
  109.      {
  110.      printf("%s: (%s is set to %s)\n",VPREFIX,CFINPUTSVAR,sp);
  111.      }
  112.       
  113.       printf("%s: Can't open file %s\n",VPREFIX,VINPUTFILE);
  114.       exit (1);
  115.       }
  116.  
  117.    strcpy(VCURRENTFILE,VINPUTFILE);
  118.  
  119.    Debug("BEGIN PARSING %s\n",VCURRENTFILE);
  120.  
  121.    LINENUMBER=1;
  122.  
  123.    while (!feof(yyin))
  124.       { 
  125.       yyparse();
  126.  
  127.       if (ferror(yyin))  /* abortable */
  128.      {
  129.      printf("%s: Error reading %s\n",VPREFIX,VCURRENTFILE);
  130.      perror("cfengine");
  131.      exit(1);
  132.      }
  133.       }
  134.  
  135.    fclose (yyin);
  136.  
  137.    alarm(0);
  138.    signal(SIGALRM,SIG_DFL);
  139.    InstallPending(ACTION);
  140.    }
  141.    
  142. for (ptr = VIMPORT; ptr != NULL; ptr=ptr->next)
  143.    {
  144.    if (IsExcluded(ptr->classes))
  145.       {
  146.       continue;
  147.       }
  148.  
  149.    Verbose("Import file %s\n",ptr->name);
  150.    
  151.    filename[0] = '\0';
  152.  
  153.    if ((sp=getenv(CFINPUTSVAR)) != NULL)
  154.       {
  155.       if (! IsAbsoluteFileName(ptr->name))   
  156.          { 
  157.          strcpy(filename,sp);
  158.          if (filename[strlen(filename)-1] != '/')
  159.             {
  160.             strcat(filename,"/");
  161.             }
  162.          }
  163.       }
  164.  
  165.    strcat(filename,ptr->name);
  166.  
  167.    signal(SIGALRM,(void *)TimeOut);
  168.    alarm(RPCTIMEOUT);
  169.  
  170.    if (! FileSecure(filename))
  171.       {
  172.       CfLog(cferror,"Skipping file","");
  173.       continue;
  174.       }
  175.    
  176.    if ((yyin = fopen(filename,"r")) == NULL) 
  177.       {
  178.       if (sp == NULL)
  179.          {
  180.          printf("%s: (%s is set to <nothing>)\n",VPREFIX,CFINPUTSVAR);
  181.          }
  182.       
  183.       Verbose("Can't open input file %s\n",filename);
  184.       continue;
  185.       }
  186.  
  187.    LINENUMBER = 1;
  188.    strcpy(VCURRENTFILE,ptr->name);
  189.  
  190.    Debug("PARSING FILE (%s)\n\n",ptr->name);
  191.  
  192.    while (!feof(yyin))
  193.       { 
  194.       yyparse();
  195.  
  196.       if (ferror(yyin))  /* abortable */
  197.      {
  198.      printf("%s: Error reading %s\n",VPREFIX,VCURRENTFILE);
  199.      perror("cfengine");
  200.      exit(1);
  201.      }
  202.       }
  203.    
  204.    alarm(0);
  205.    signal(SIGALRM,SIG_DFL);
  206.    fclose (yyin);
  207.    InstallPending(ACTION);
  208.    }
  209.  
  210. VCURRENTFILE[0]='\0';       /* Zero filename for subsequent errors */
  211.  
  212. Debug("(END OF PARSING)\n");
  213. }
  214.  
  215. /*******************************************************************/
  216.  
  217. SetAction (action)
  218.  
  219. enum actions action;
  220.  
  221. {
  222. InstallPending(ACTION);   /* Flush any existing actions */
  223.  
  224. Debug1("\nBEGIN NEW ACTION %s\n",ACTIONTEXT[action]);
  225.  
  226. ACTION = action;
  227. strcpy(ACTIONBUFF,ACTIONTEXT[action]);
  228.  
  229. switch (ACTION)
  230.    {
  231.    case interfaces:
  232.    case files:
  233.    case makepath:
  234.    case tidy:
  235.    case disable:
  236.    case image:
  237.    case links:
  238.    case required:
  239.    case shellcommands:
  240.    case unmounta:
  241.    case processes:  InitializeAction();
  242.    }
  243.  
  244. CURRENTAUTHPATH[0] = '\0';
  245.  
  246. strcpy(CLASSBUFF,"any");    /* default class */
  247. }
  248.  
  249. /*******************************************************************/
  250.  
  251. HandleId(id)
  252.  
  253. char *id;
  254.  
  255. {
  256. Debug1("HandleId(%s)\n",id);
  257.  
  258. if (ACTION == control)
  259.    {
  260.    if ((CONTROLVAR = ScanVariable(id)) != nonexistentvar)
  261.       {
  262.       strcpy(CURRENTITEM,id);
  263.       return;
  264.       }
  265.    else
  266.       {
  267.       RecordMacroId(id);
  268.       return;
  269.       }
  270.    }
  271.  
  272. if (ACTION == groups)
  273.    { int count = 1;
  274.      char *cid = id;
  275.  
  276.    while (*cid != '\0')
  277.       {
  278.       if (*cid++ == '.')
  279.          {
  280.          count++;
  281.          }
  282.       }
  283.  
  284.    if (strcmp(id,"any") == 0)
  285.       {
  286.       yyerror("Reserved class <any>");
  287.       }
  288.  
  289.    if (count > 1)                              /* compound class */
  290.       {
  291.       yyerror("Group with compound identifier");
  292.       FatalError("Dots [.] not allowed in group identifiers");
  293.       }
  294.  
  295.    if (IsHardClass(id))
  296.       {
  297.       yyerror("Reserved class name (choose a different name)");
  298.       }
  299.  
  300.    strcpy(GROUPBUFF,id);
  301.    }
  302.  
  303.  
  304. switch(ACTION)   /* Check for IP names in cfd */
  305.    {
  306.    case admit:
  307.                  InstallAuthItem(CURRENTAUTHPATH,id,&VADMIT,&VADMITTOP,CLASSBUFF);
  308.          break;
  309.    case deny:
  310.                  InstallAuthItem(CURRENTAUTHPATH,id,&VDENY,&VDENYTOP,CLASSBUFF);
  311.          break;
  312.  
  313.    case acls:
  314.                  Debug1("ACL-alias: %s\n",id);
  315.          strcpy(CURRENTITEM,id);
  316.                  InstallACL(id,CLASSBUFF);
  317.          break;
  318.    }
  319.  
  320.  
  321.  
  322. strcpy(CLASSBUFF,"any");    /* default class */
  323. }
  324.  
  325. /*******************************************************************/
  326.  
  327. HandleClass (id)
  328.  
  329. char *id;
  330.  
  331. { int members;
  332.  
  333. InstallPending(ACTION);
  334.  
  335. Debug1("HandleClass(%s)\n",id);
  336.  
  337. if ((members = CompoundId(id)) > 1)             /* Parse compound id */
  338.    {
  339.    Debug1("Compound class = (%s) with %d members\n",id,members);
  340.    }
  341. else
  342.    {
  343.    Debug1("Simple identifier or class = (%s)\n",id);
  344.    CONTROLVAR = ScanVariable(id);
  345.    }
  346.  
  347. Debug1("HandleClass(end)\n");
  348. }
  349.  
  350. /*******************************************************************/
  351.  
  352. HandleItem (item)
  353.  
  354. char *item;
  355.  
  356. {
  357. Debug1("HandleItem(%s)\n",item);
  358.  
  359. if (strcmp(item,"+") == 0 || strcmp(item,"-") == 0)
  360.    {
  361.    yyerror("+/- not bound to identifier");
  362.    }
  363.  
  364. if (item[0] == '+')                               /* Lookup in NIS */
  365.    {
  366.    item++;
  367.  
  368.    if (item[0] == '@')                               /* Irrelevant */
  369.       {
  370.       item++;
  371.       }
  372.  
  373.    Debug1("Netgroup item, lookup NIS group (%s)\n",item);
  374.  
  375.    strcpy(CURRENTITEM,item);
  376.  
  377.    if (ACTION == groups)
  378.       {
  379.       HandleGroupItem(item,netgroup);
  380.       }
  381.    else
  382.       {
  383.       yyerror("Netgroup reference outside group: action or illegal octal number");
  384.       FatalError("Netgroups may only define internal groups or illegal octal file action.");
  385.       }
  386.    }
  387. else if ((item[0] == '-') && (ACTION != processes))
  388.    {
  389.    item++;
  390.  
  391.    if (item[0] == '@')                               /* Irrelevant */
  392.       {
  393.       item++;
  394.  
  395.       if (ACTION == groups)
  396.          {
  397.          HandleGroupItem(item,groupdeletion);
  398.          }
  399.       else
  400.          {
  401.          yyerror("Netgroup reference outside group: action or illegal octal number");
  402.          FatalError("Netgroups may only define internal groups or illegal octal file action.");
  403.          }
  404.       }
  405.    else
  406.       {
  407.       if (ACTION == groups)
  408.          {
  409.          HandleGroupItem(item,deletion);
  410.          }
  411.       else
  412.          {
  413.      if (ACTION != processes)
  414.         {
  415.         yyerror("Illegal deletion sign or octal number?");
  416.         FatalError("The deletion operator may only be in the groups: action");
  417.         }
  418.          }
  419.       }
  420.  
  421.  
  422.    }
  423. else if (item[0] == '\"' || item[0] == '\'' || item[0] == '`') 
  424.    {
  425.    *(item+strlen(item)-1) = '\0';
  426.  
  427.    if (ACTION == groups)                     /* This test should be redundant */
  428.       {
  429.       HandleGroupItem(item,classscript);
  430.       }
  431.    }
  432. else
  433.    {
  434.    Debug1("simple item = (%s)\n",item);
  435.   
  436.    /* CONTROLVAR set by CompoundId via HandleId */
  437.  
  438.    switch(ACTION)
  439.       {
  440.       case control:     InstallLocalInfo(item);
  441.                         break;
  442.       case groups:      HandleGroupItem(item,simple);
  443.                         break;
  444.       case resolve:     AppendNameServer(item);
  445.                         break;
  446.       case image:
  447.       case files:       HandleFileItem(item);
  448.                         break;
  449.       case tidy:        strcpy(CURRENTITEM,item);
  450.                         break;
  451.       case homeservers: InstallHomeserverItem(item);
  452.                         break;
  453.       case binservers:  InstallBinserverItem(item);
  454.                         break;
  455.       case mailserver:  yyerror("Give whole rpc path to mailserver");
  456.                         break;
  457.       case required:    yyerror("Required filesystem must be an absolute path");
  458.                         FatalError("Fatal error");
  459.                         break;
  460.       case mountables:  yyerror("Mountables should be specified by an absolute pathname");
  461.                         break;
  462.       case links:       if (ACTION_IS_LINKCHILDREN && strcmp (item,"linkchildren") == 0)
  463.                            {
  464.                            strcpy(LINKTO,item);
  465.                            }
  466.                         else
  467.                            {
  468.                            yyerror("Links requires path or varitem");
  469.                            }
  470.                         break;
  471.       case import:      AppendImport(item);
  472.                         break;
  473.       case shellcommands:
  474.                     InstallPending(ACTION);
  475.             strcpy(CURRENTPATH,item);
  476.             ACTIONPENDING = true;
  477.                         break;
  478.       case makepath:    yyerror("makepath needs an abolute pathname");
  479.                         FatalError("Fatal Error");
  480.       case disable:     yyerror("disable needs an absolute path name");
  481.                         FatalError("Fatal Error");
  482.       case broadcast:   InstallBroadcastItem(item);
  483.                         break;
  484.             
  485.       case interfaces:  if (strlen(VIFNAME)==0)
  486.                        {               
  487.                strcpy(VIFNAME,item);
  488.                }
  489.                         else
  490.                {
  491.                InstallPending(ACTION);
  492.                strcpy(VIFNAME,item);
  493.                }
  494.                     break;
  495.             
  496.       case defaultroute:InstallDefaultRouteItem(item);
  497.                         break;
  498.       case misc_mounts: if (MOUNT_FROM && MOUNT_ONTO && ((strcmp(item,"rw") == 0 || strcmp(item,"ro") == 0)))
  499.                            {
  500.                Debug1("Miscmount mode found, old style\n");
  501.                
  502.                if (strcmp(item,"rw") == 0)
  503.                   {
  504.                   MOUNTMODE='w';
  505.                   break;
  506.                   }
  507.                
  508.                if (strcmp(item,"ro") == 0)
  509.                   {
  510.                   MOUNTMODE='o';
  511.                   break;
  512.                   }
  513.                }
  514.       
  515.                         yyerror("miscmounts: host:/frompath /mounton_path ro|rw\n");
  516.                         break;
  517.  
  518.       case unmounta:    yyerror("Umount must be in the format machine:directory");
  519.                         break;
  520.  
  521.       case editfiles:   /* action recorded in CURRENTITEM, installed from qstring in lexer */
  522.                         strcpy(CURRENTITEM,item);
  523.                         break;
  524.  
  525.       case ignore:      AppendIgnore(item);
  526.                         break;
  527.  
  528.       case processes:   if (strcmp(item,"restart") == 0)
  529.                        {
  530.                HAVE_RESTART = true;
  531.                ACTIONPENDING = false;
  532.                return;
  533.                }
  534.  
  535.                         if (ACTIONPENDING)
  536.                {
  537.                InstallPending(ACTION);          /* Flush any existing actions */
  538.                            InitializeAction();
  539.                }
  540.       
  541.                         if (strcmp(item,"SetOptionString") == 0)
  542.                {
  543.                Debug("Found SetOptionString\n");
  544.                            if (EXPR[0] == '\0')
  545.                   {
  546.                      strcpy(EXPR,item);
  547.                   ACTIONPENDING = false;
  548.                   HAVE_RESTART = true;    /* save option string in restart */
  549.                   return;
  550.                   }
  551.                else
  552.                   {
  553.                   yyerror("Inappropriate placement of SetOptionString");
  554.                   return;
  555.                   }
  556.                }
  557.  
  558.                     if (EXPR[0] == '\0')
  559.                        {
  560.                if (HAVE_RESTART)
  561.                   {
  562.                   yyerror("Missing search expression");
  563.                   }
  564.                strcpy(EXPR,item);
  565.                ACTIONPENDING = true;
  566.                }
  567.                         else
  568.                {
  569.                if (HAVE_RESTART)
  570.                   {
  571.                   strcpy(RESTART,item);
  572.                   HAVE_RESTART= false;
  573.                   ACTIONPENDING = true;
  574.                   }
  575.                }
  576.                         break;
  577.  
  578.       default:          yyerror("Unknown item or out of context");
  579.       }
  580.    }
  581. }
  582.  
  583. /***************************************************************************/
  584.  
  585. HandlePath (path)
  586.  
  587. char *path;
  588.  
  589. {
  590. if (ACTION == processes && ! ACTIONPENDING)
  591.    {
  592.    }
  593. else
  594.    {
  595.    InstallPending(ACTION);           /* Flush any existing actions */
  596.    InitializeAction();                 /* Clear data for files/dirs  */
  597.    }
  598.  
  599. Debug1("path = (%s)\n",path);
  600.  
  601. strcpy(CURRENTPATH,path);                   /* Yes this must be here */
  602.  
  603. ACTIONPENDING = true;                     /* we're parsing an action */
  604.  
  605. if (ACTION_IS_LINK || ACTION_IS_LINKCHILDREN)  /* to-link (after ->) */
  606.    {
  607.    strcpy(LINKTO,CURRENTPATH);
  608.    }
  609. else
  610.    {
  611.    switch (ACTION)
  612.       {
  613.       case control:  if (CONTROLVAR == cfmountpat)
  614.                         {
  615.                         SetMountPath(path);
  616.             break;
  617.                         }
  618.  
  619.                      if (CONTROLVAR == cfrepos)
  620.             {
  621.             SetRepository(path);
  622.             break;
  623.             }
  624.  
  625.              if (CONTROLVAR == cfrepchar)
  626.             {
  627.             if (strlen(path) > 1)
  628.                {
  629.                yyerror("reposchar can only be a single letter");
  630.                break;
  631.                }
  632.             if (path[0] == '/')
  633.                {
  634.                yyerror("illegal value for reposchar");
  635.                break;
  636.                }
  637.             REPOSCHAR = path[0];
  638.             }
  639.  
  640.              if (CONTROLVAR == cflistsep)
  641.             {
  642.             if (strlen(path) > 1)
  643.                {
  644.                yyerror("listseparator can only be a single letter");
  645.                break;
  646.                }
  647.             if (path[0] == '/')
  648.                {
  649.                yyerror("illegal value for listseparator");
  650.                break;
  651.                }
  652.             LISTSEPARATOR = path[0];
  653.             }
  654.  
  655.                      if (CONTROLVAR == cfhomepat)
  656.                         {
  657.                         yyerror("Path relative to mountpath required");
  658.                         FatalError("Absolute path was specified\n");
  659.                         }
  660.  
  661.                     if (CONTROLVAR == nonexistentvar)
  662.                        {
  663.                        AddMacroValue(CURRENTITEM,path);
  664.                        }
  665.  
  666.                        break;
  667.       case import:     AppendImport(path);
  668.                        break;
  669.       case links:      /* from link (see cf.l) */
  670.                        break;
  671.                
  672.       case required:   strcpy(CURRENTPATH,path);
  673.                        break;
  674.       case shellcommands:
  675.                        break;
  676.       case mountables: AppendMountable(path);
  677.                        break;
  678.       case mailserver: InstallMailserverPath(path);
  679.                        break;
  680.       case tidy:       strcpy(CURRENTITEM,path);
  681.                        break;
  682.       case disable:    strcpy(CURRENTPATH,path);
  683.                        ACTIONPENDING = true;
  684.                        break;
  685.       case makepath:   strcpy(CURRENTPATH,path);
  686.                        break;
  687.       case ignore:     AppendIgnore(path);
  688.                        break;
  689.  
  690.       case misc_mounts:if (! MOUNT_FROM)
  691.                           {
  692.                           MOUNT_FROM = true;
  693.                           strcpy(MOUNTFROM,CURRENTPATH);
  694.                           }
  695.                        else
  696.                           {
  697.                           if (MOUNT_ONTO)
  698.                 {
  699.                             yyerror ("Path not expected");
  700.                             FatalError("miscmounts: syntax error");
  701.                             }
  702.                           MOUNT_ONTO = true;
  703.                           strcpy(MOUNTONTO,CURRENTPATH);
  704.                           }
  705.                        break;
  706.  
  707.       case unmounta:   strcpy(CURRENTPATH,path);
  708.                        break;
  709.       case image:
  710.       case files:      
  711.                        break;
  712.  
  713.       case editfiles:  /* file recorded in CURRENTPATH */
  714.                        break;
  715.  
  716.       case processes:   if (EXPR[0] == '\0')
  717.                        {
  718.                if (HAVE_RESTART)
  719.                   {
  720.                   yyerror("Missing search expression");
  721.                   }
  722.                strcpy(EXPR,path);
  723.                }
  724.                         else
  725.                {
  726.                if (HAVE_RESTART)
  727.                   {
  728.                   strcpy(RESTART,path);
  729.                   HAVE_RESTART = false;
  730.                   ACTIONPENDING = true;
  731.                   }
  732.                }
  733.                break;
  734.  
  735.       default:         yyerror("Unknown command or name out of context");
  736.       }
  737.    }
  738. }
  739.  
  740. /*******************************************************************/
  741.  
  742. HandleVarpath(varpath)         
  743.  
  744.   /* Expand <binserver> and <fac> etc. Note that the right hand  */
  745.   /* side of links etc. gets expanded at runtime. <binserver> is */
  746.   /* only legal on the right hand side.                          */
  747.  
  748. char *varpath;
  749.  
  750. {
  751. InstallPending(ACTION);   /* Flush any existing actions */
  752. InitializeAction();
  753.  
  754. Debug1("HandleVarpath(%s)\n",varpath);
  755.  
  756. if (IsWildCard(varpath) && ! (ACTION == files || ACTION == tidy || ACTION == admit || ACTION == deny || ACTION == import))
  757.    {
  758.    yyerror("Wildcards cannot be used in this context (possibly missing space?)");
  759.    }
  760.  
  761. strcpy(CURRENTPATH,varpath);
  762.  
  763. ACTIONPENDING = true;
  764.  
  765. if (ACTION_IS_LINK || ACTION_IS_LINKCHILDREN)
  766.    {
  767.    strcpy(LINKTO,varpath);
  768.    }
  769. else 
  770.    {
  771.    switch (ACTION)
  772.       {
  773.       case tidy:       strcpy(CURRENTITEM,varpath);
  774.                        break;
  775.                
  776.       case required:   strcpy(CURRENTPATH,varpath);
  777.                        break;
  778.                
  779.       case makepath:   strcpy(CURRENTPATH,varpath);
  780.                        break;
  781.                
  782.       case control:    if (CONTROLVAR == cfmountpat)
  783.                           {
  784.                           SetMountPath(varpath);
  785.               break;
  786.                           }
  787.       
  788.                         if (CONTROLVAR == cfrepos)
  789.                {
  790.                SetRepository(varpath);
  791.                break;
  792.                }
  793.  
  794.              if (CONTROLVAR == cfrepchar)
  795.             {
  796.             if (strlen(varpath) > 1)
  797.                {
  798.                yyerror("reposchar can only be a single letter");
  799.                break;
  800.                }
  801.             if (varpath[0] == '/')
  802.                {
  803.                yyerror("illegal value for reposchar");
  804.                break;
  805.                }
  806.             REPOSCHAR = varpath[0];
  807.             }
  808.  
  809.              if (CONTROLVAR == cflistsep)
  810.             {
  811.             if (strlen(varpath) > 1)
  812.                {
  813.                yyerror("listseparator can only be a single letter");
  814.                break;
  815.                }
  816.             if (varpath[0] == '/')
  817.                {
  818.                yyerror("illegal value for listseparator");
  819.                break;
  820.                }
  821.             LISTSEPARATOR = varpath[0];
  822.             }            
  823.  
  824.                         if (CONTROLVAR == cfhomepat)
  825.                            {
  826.                            yyerror("Home-pattern should be relative to mount-path, not absolute");
  827.                            }
  828.  
  829.                         if (CONTROLVAR == nonexistentvar)
  830.                            {
  831.                            yyerror("Nested macros not permitted");
  832.                            }
  833.                         break;
  834.  
  835.       case ignore:      AppendIgnore(varpath);
  836.                         break;
  837.  
  838.  
  839.       case import:      AppendImport(varpath);
  840.                     break;
  841.             
  842.       case links:       /* FROM LINK */
  843.                     break;
  844.  
  845.       case defaultroute:InstallDefaultRouteItem(varpath);
  846.                         break;
  847.       case image:
  848.       case files:
  849.       case editfiles:
  850.                         break;
  851.  
  852.       case disable:    strcpy(CURRENTPATH,varpath);
  853.                        ACTIONPENDING = true;
  854.                        break;
  855.                
  856.       case processes:   if (EXPR[0] == '\0')
  857.                        {
  858.                if (HAVE_RESTART)
  859.                   {
  860.                   yyerror("Missing search expression");
  861.                   }
  862.                strcpy(EXPR,varpath);
  863.                }
  864.                         else
  865.                {
  866.                if (HAVE_RESTART)
  867.                   {
  868.                   strcpy(RESTART,varpath);
  869.                   HAVE_RESTART = false;
  870.                   ACTIONPENDING = true;
  871.                   }
  872.                }
  873.       
  874.                 break;
  875.  
  876.       case unmounta:    strcpy(CURRENTPATH,varpath);
  877.                     break;
  878.  
  879.       case deny:
  880.       case admit:       Debug("admit/deny varpath=%s\n",varpath);
  881.                     strcpy(CURRENTAUTHPATH,varpath);
  882.                     break;
  883.  
  884.       case groups:      yyerror("Variables in groups/classes need to be quoted");
  885.  
  886.       default:          yyerror("Variable or name out of context");
  887.       }
  888.    }
  889. }
  890.  
  891. /*******************************************************************/
  892.  
  893. HandleWildcard(wildcard)
  894.  
  895. char *wildcard;
  896.  
  897. {
  898. Debug1("wildcard = (%s)\n",wildcard);
  899.  
  900. ACTIONPENDING = true;
  901.  
  902. switch (ACTION)
  903.  
  904.    {
  905.    case ignore: AppendIgnore(wildcard);
  906.                 break;
  907.  
  908.    case control: 
  909.                  if (CONTROLVAR == cfhomepat)
  910.                      {
  911.                      if (*wildcard == '/')
  912.                         {
  913.                         yyerror("Home pattern specified as absolute path (should be relative to mountpath)");
  914.                         }
  915.  
  916.  
  917.                      Debug1(">>Installing wildcard %s as a home pattern\n",wildcard);
  918.                      HandleHomePattern(wildcard);
  919.              }
  920.                  else if (CONTROLVAR == nonexistentvar)
  921.                      {
  922.                      AddMacroValue(CURRENTITEM,wildcard);
  923.                      }
  924.                  else if ( CONTROLVAR == cfexcludecp ||
  925.                CONTROLVAR == cfexcludeln ||
  926.                     CONTROLVAR == cfcplinks   ||
  927.                            CONTROLVAR == cflncopies  ||
  928.                    CONTROLVAR == cfrepchar   ||
  929.                            CONTROLVAR == cflistsep   )
  930.             {
  931.                     if (*wildcard == '/')
  932.                        {
  933.                        yyerror("Pattern should be a relative name, not an absolute path");
  934.                        }
  935.                     InstallLocalInfo(wildcard);
  936.                     }
  937.                  else
  938.                     {
  939.                     RecordMacroId(wildcard);
  940.                     }
  941.                  break;
  942.          
  943.    case files:
  944.                  HandleOptionalFileAttribute(wildcard);
  945.          break;
  946.    case image:
  947.                  HandleOptionalImageAttribute(wildcard);
  948.          break;
  949.    case tidy:
  950.                  HandleOptionalTidyAttribute(wildcard);
  951.                  break;
  952.          
  953.    case makepath:
  954.                  HandleOptionalDirAttribute(wildcard);
  955.          break;
  956.  
  957.    case disable:
  958.                  HandleOptionalDisableAttribute(wildcard);
  959.                  break;
  960.    case links:
  961.                  HandleOptionalLinkAttribute(wildcard);
  962.                  break;
  963.    case processes:
  964.                  HandleOptionalProcessAttribute(wildcard);
  965.                  break;
  966.  
  967.    case misc_mounts:
  968.  
  969.                  if (!MOUNT_FROM)
  970.             {
  971.             MOUNT_FROM = true;
  972.             strcpy(MOUNTFROM,wildcard);
  973.             ACTIONPENDING = false;
  974.             }
  975.          else if (!MOUNT_ONTO)
  976.             {
  977.             MOUNT_ONTO = true;
  978.             strcpy(MOUNTONTO,wildcard);
  979.             ACTIONPENDING = false;
  980.             }
  981.          else
  982.             {
  983.             HandleOptionalMiscMountsAttribute(wildcard);
  984.             }
  985.          break;
  986.  
  987.    case unmounta:
  988.                  HandleOptionalUnMountAttribute(wildcard);
  989.          break;
  990.          
  991.    case shellcommands:
  992.                  HandleOptionalScriptAttribute(wildcard);
  993.          break;
  994.  
  995.    case required:
  996.                  HandleOptionalRequired(wildcard);
  997.          break;
  998.  
  999.    case interfaces:
  1000.                  HandleOptionalInterface(wildcard);
  1001.          break;
  1002.  
  1003.    case admit:
  1004.                  InstallAuthItem(CURRENTAUTHPATH,wildcard,&VADMIT,&VADMITTOP,CLASSBUFF);
  1005.          break;
  1006.    case deny:
  1007.                  InstallAuthItem(CURRENTAUTHPATH,wildcard,&VDENY,&VDENYTOP,CLASSBUFF);
  1008.          break;
  1009.  
  1010.    case acls:
  1011.                  AddACE(CURRENTITEM,wildcard,CLASSBUFF);
  1012.          break;
  1013.  
  1014.    case import:  AppendImport(wildcard);
  1015.                  break;
  1016.  
  1017.    default:
  1018.                  yyerror("Wildcards cannot be used in this context:");
  1019.    }
  1020. }
  1021.  
  1022.  
  1023. /*******************************************************************/
  1024. /* Level 2                                                         */
  1025. /*******************************************************************/
  1026.  
  1027. CompoundId(id)                       /* check for dots in the name */
  1028.  
  1029. char *id;
  1030.  
  1031. { int count = 1;
  1032.   char *cid = id;
  1033.  
  1034. for (cid = id; *cid != '\0'; cid++)
  1035.    {
  1036.    if (*cid == '.' || *cid == '|')
  1037.       {
  1038.       count++;
  1039.       }
  1040.    }
  1041.  
  1042. bzero(CLASSBUFF,bufsize);
  1043. strcpy(CLASSBUFF,id);
  1044.  
  1045. return(count);
  1046. }
  1047.  
  1048. /*******************************************************************/
  1049.  
  1050. ShellCommandReturnsZero(comm)
  1051.  
  1052. char *comm;
  1053.  
  1054. { int status, i, argc;
  1055.   pid_t pid;
  1056.   char arg[maxshellargs][bufsize];
  1057.   char **argv;
  1058.  
  1059. /* Build argument array */
  1060.  
  1061. for (i = 0; i < maxshellargs; i++)
  1062.    {
  1063.    bzero (arg[i],bufsize);
  1064.    }
  1065.  
  1066. argc = SplitCommand(comm,arg);
  1067.  
  1068. if (argc == -1)
  1069.    {
  1070.    sprintf(OUTPUT,"Too many arguments in %s\n",comm);
  1071.    CfLog(cferror,OUTPUT,"");
  1072.    return false;
  1073.    }
  1074.     
  1075. if ((pid = fork()) < 0)
  1076.    {
  1077.    FatalError("Failed to fork new process");
  1078.    }
  1079. else if (pid == 0)                     /* child */
  1080.    {
  1081.    argv = (char **) malloc((argc+1)*sizeof(char *));
  1082.  
  1083.    if (argv == NULL)
  1084.       {
  1085.       FatalError("Out of memory");
  1086.       }
  1087.    
  1088.    for (i = 0; i < argc; i++)
  1089.       {
  1090.       argv[i] = arg[i];
  1091.       }
  1092.  
  1093.    argv[i] = (char *) NULL;
  1094.  
  1095.    if (execv(arg[0],argv) == -1)
  1096.       {
  1097.       yyerror("script failed");
  1098.       perror("execvp");
  1099.       exit(1);
  1100.       }
  1101.    }
  1102. else                                    /* parent */
  1103.    {
  1104.    if (wait(&status) != pid)
  1105.       {
  1106.       sprintf(OUTPUT,"Wait for child failed\n");
  1107.       CfLog(cfinform,OUTPUT,"wait");
  1108.       return false;
  1109.       }
  1110.    else
  1111.       {
  1112.       if (WIFSIGNALED(status))
  1113.          {
  1114.          Debug("Script %s returned: %d\n",comm,WTERMSIG(status));
  1115.          return false;
  1116.          }
  1117.  
  1118.       if (! WIFEXITED(status))
  1119.          {
  1120.          return false;
  1121.          }
  1122.  
  1123.       if (WEXITSTATUS(status) == 0)
  1124.          {
  1125.          return true;
  1126.          }
  1127.       else
  1128.          {
  1129.          return false;
  1130.          }
  1131.       }
  1132.    }
  1133.  
  1134. return false;
  1135. }
  1136.  
  1137.  
  1138. /*******************************************************************/
  1139. /* Toolkits Misc                                                   */
  1140. /*******************************************************************/
  1141.  
  1142. InitializeAction()                                   /* Set defaults */
  1143.  
  1144.  {
  1145.  Debug1("InitializeAction()\n");
  1146.  
  1147.  PLUSMASK = (mode_t)0;
  1148.  MINUSMASK = (mode_t)0;
  1149.  PLUSFLAG = (u_long)0;
  1150.  MINUSFLAG = (u_long)0;
  1151.  VRECURSE = 0;
  1152.  VAGE = 99999;
  1153.  VUIDNAME[0] = '*';
  1154.  VUIDNAME[1] = '\0';
  1155.  VGIDNAME[0] = '*';
  1156.  VGIDNAME[1] = '\0';
  1157.  HAVE_RESTART = 0;
  1158.  FILEACTION=warnall;
  1159.  CURRENTPATH[0] = '\0';
  1160.  CURRENTITEM[0] = '\0';
  1161.  ACTIONPENDING = false;
  1162.  DESTINATION[0] = '\0';
  1163.  IMAGEACTION[0] = '\0';
  1164.  strcpy(VIFNAME,"");
  1165.  PTRAVLINKS = (short) '?';
  1166.  FORCECOPY = false;
  1167.  IMAGEBACKUP = true;
  1168.  SECURE = false;
  1169.  ROTATE=0;
  1170.  TIDYSIZE=0;
  1171.  PROMATCHES=-1;
  1172.  PROSIGNAL=0; 
  1173.  AGETYPE='a';
  1174.  COPYTYPE = DEFAULTCOPYTYPE; /* 't' */
  1175.  LINKDIRS = 'k';
  1176.  USESHELL = 'y';
  1177.  LOGP = 'd';
  1178.  INFORMP = 'd';
  1179.  PURGE = 'n';
  1180.  CHECKSUM = 'n';
  1181.  TIDYDIRS = false;
  1182.  VEXCLUDEPARSE = NULL;
  1183.  VINCLUDEPARSE = NULL;
  1184.  VIGNOREPARSE = NULL;
  1185.  VACLBUILD = NULL;
  1186.  VCPLNPARSE = NULL;
  1187.  VTIMEOUT=0;
  1188.  strcpy(ALLCLASSBUFFER,"");
  1189.  strcpy(CFSERVER,"localhost");
  1190.  DISCOMP='>';
  1191.  DISABLESIZE=cfnosize;
  1192.  DELETEDIR = 't';   /* t=true */
  1193.  DELETEFSTAB = 't';
  1194.  FORCE = 'f';
  1195.  STEALTH = 'f';
  1196.  
  1197.  if (MOUNT_FROM && MOUNT_ONTO)
  1198.     {
  1199.     Debug("Resetting miscmount data\n");
  1200.     MOUNT_FROM = false;
  1201.     MOUNT_ONTO = false;
  1202.     MOUNTMODE='w';
  1203.     MOUNTFROM[0] = '\0';
  1204.     MOUNTONTO[0] = '\0';
  1205.     }
  1206.  
  1207.  /* Make sure we don't clean the buffer in the middle of a link! */
  1208.  
  1209.  if ( ! ACTION_IS_LINK && ! ACTION_IS_LINKCHILDREN)
  1210.     {
  1211.     LINKFROM[0] = '\0';
  1212.     LINKTO[0] = '\0';
  1213.     LINKSILENT = false;
  1214.     LINKTYPE = 's';
  1215.     DEADLINKS = false;
  1216.     }
  1217.  }
  1218.  
  1219. /*********************************************************************/
  1220.  
  1221. SetMountPath (value)
  1222.  
  1223. char *value;
  1224.  
  1225.  { char buff[bufsize];
  1226.  
  1227.  bzero(buff,bufsize);
  1228.  
  1229.  ExpandVarstring(value,buff,"");
  1230.  
  1231.  Debug("Appending [%s] to mountlist\n",buff);
  1232.  
  1233.  AppendItem(&VMOUNTLIST,buff,CLASSBUFF);
  1234.  }
  1235.  
  1236. /*********************************************************************/
  1237.  
  1238. SetRepository (value)
  1239.  
  1240. char *value;
  1241.  
  1242.  {
  1243.   if (*value != '/')
  1244.      {
  1245.      yyerror("File repository must be an absolute directory name");
  1246.      }
  1247.   
  1248.   if (VREPOSITORY[0] != '\0')
  1249.      {
  1250.      yyerror("Redefinition of system variable repository");
  1251.      }
  1252.  
  1253.   ExpandVarstring(value,VREPOSITORY,"");
  1254.  }
  1255.  
  1256. /* EOF */
  1257.